#include "textbubble.h"
#include <QFontMetricsF>
#include <QDebug>
#include <QFont>
#include "global.h"
#include <QTimer>
#include <QTextDocument>
#include <QTextBlock>
#include <QTextLayout>
#include <QFont>

// 构造函数，用于创建文本气泡对象
// role: 聊天角色，用于区分不同的聊天身份
// text: 要显示的文本内容
// parent: 父级窗口部件
TextBubble::TextBubble(ChatRole role, const QString &text, QWidget *parent)
    :BubbleFrame(role, parent)
{
    // 创建一个只读的 QTextEdit 对象，用于显示文本
    m_pTextEdit = new QTextEdit();
    // 设置为只读模式，用户不能编辑文本
    m_pTextEdit->setReadOnly(true);
    // 隐藏垂直滚动条
    m_pTextEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    // 隐藏水平滚动条
    m_pTextEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    // 为 QTextEdit 安装事件过滤器，以便处理特定事件
    m_pTextEdit->installEventFilter(this);
    // 创建一个字体对象，使用微软雅黑字体，字号为 12
    QFont font("Microsoft YaHei");
    font.setPointSize(12);
    // 设置 QTextEdit 的字体
    m_pTextEdit->setFont(font);
    // 设置文本内容
    setPlainText(text);
    // 将 QTextEdit 设置为气泡框架的子部件
    setWidget(m_pTextEdit);
    // 初始化样式表
    initStyleSheet();
}

// 事件过滤器，用于处理特定对象的事件
// o: 事件发生的对象
// e: 事件对象
bool TextBubble::eventFilter(QObject *o, QEvent *e)
{
    // 检查事件发生的对象是否为 m_pTextEdit，并且事件类型是否为绘制事件
    if(m_pTextEdit == o && e->type() == QEvent::Paint)
    {
        // 在绘制事件中调整文本高度
        adjustTextHeight();
    }
    // 调用父类的事件过滤器处理其他事件
    return BubbleFrame::eventFilter(o, e);
}

// 设置纯文本内容，并根据文本内容调整气泡的最大宽度
// text: 要设置的纯文本内容
void TextBubble::setPlainText(const QString &text)
{
    // 设置 QTextEdit 的纯文本内容
    m_pTextEdit->setPlainText(text);
    // 文档的边距
    qreal doc_margin = m_pTextEdit->document()->documentMargin();
    // 布局左边的边距
    int margin_left = this->layout()->contentsMargins().left();
    // 布局右边的边距
    int margin_right = this->layout()->contentsMargins().right();
    // 创建字体度量对象，用于获取字体的相关信息
    QFontMetricsF fm(m_pTextEdit->font());
    // 获取 QTextEdit 的文档对象
    QTextDocument *doc = m_pTextEdit->document();
    // 初始化最大宽度为 0
    int max_width = 0;
    // 遍历文档中的每一段文本
    for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())
    {
        // 获取当前段落文本的宽度
        int txtW = int(fm.horizontalAdvance(it.text()));
        // 更新最大宽度
        max_width = max_width < txtW ? txtW : max_width;
    }
    // 设置气泡的最大宽度，考虑文档边距和布局边距
    setMaximumWidth(max_width + doc_margin * 2 + (margin_left + margin_right));
}

// 调整文本气泡的高度，使其能够完整显示文本内容
void TextBubble::adjustTextHeight()
{
    // 文档的边距
    qreal doc_margin = m_pTextEdit->document()->documentMargin();
    // 获取 QTextEdit 的文档对象
    QTextDocument *doc = m_pTextEdit->document();
    // 初始化文本高度为 0
    qreal text_height = 0;
    // 遍历文档中的每一段文本
    for (QTextBlock it = doc->begin(); it != doc->end(); it = it.next())
    {
        // 获取当前段落的布局对象
        QTextLayout *pLayout = it.layout();
        // 获取当前段落的边界矩形
        QRectF text_rect = pLayout->boundingRect();
        // 累加段落高度
        text_height += text_rect.height();
    }
    // 布局顶部的边距
    int vMargin = this->layout()->contentsMargins().top();
    // 设置气泡的固定高度，考虑文本高度、文档边距和布局边距
    setFixedHeight(text_height + doc_margin *2 + vMargin*2 );
}

// 初始化 QTextEdit 的样式表
void TextBubble::initStyleSheet()
{
    // 设置 QTextEdit 的样式表，背景透明，无边框
    m_pTextEdit->setStyleSheet("QTextEdit{background:transparent;border:none}");
}
